package ae.pcfc.etks.online.web;

import static java.lang.String.format;

import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.ClassUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.util.UriTemplate;
import org.springframework.web.util.UriUtils;
import org.springframework.web.util.UrlPathHelper;

import ae.pcfc.etks.online.common.exception.SystemException;
import ae.pcfc.etks.online.web.common.Constants;

public class ViewUtils {

	/*
	 * so steps will be as follows 1- go define ViewPath in ViewPath (if not
	 * already defined) like company/register/nonclient 2- if the pageType is
	 * not defined go define it in PageType like add,edit,form,etc 3- use
	 * getForward or getRedirect 4- define a constant value for view if it does
	 * not follow a pattern (use with caution)
	 */

	public static final String DEFAULT_VIEW = null;
	public static final String LOGIN_VIEW = "/login";
	public static final String LOGOUT_VIEW = "/logout";

	private ViewUtils() {
	}

	public static String getForward(String viewPath, PageType pageType) {
		String viewName = ((viewPath.substring(1)).replace('/', '.'))
				.toLowerCase();
		return format("%s.%s", viewName, pageType.getPageType().toLowerCase());
	}

	public static String getForward(String viewPath, PageType pageType,
			Map<String, String> paramMap) {
		int count = 0;
		StringBuilder parms = new StringBuilder();
		for (String key : paramMap.keySet()) {
			try {
				count++;
				parms.append(key + "="
						+ UriUtils.encodeQueryParam(paramMap.get(key), "UTF-8"));

			} catch (UnsupportedEncodingException e) {
				parms.append(key + "=" + paramMap.get(key));
			} finally {
				if (count < paramMap.size())
					parms.append("&");
			}
		}
		
		String viewName = ((viewPath.substring(1)).replace('/', '.'))
				.toLowerCase();
		return format("%s.%s.htm?%s", viewName, pageType.getPageType()
				.toLowerCase(), parms.toString());
	}

	public static String getRedirect(String absoluteURL) {
		return format("redirect:%s", absoluteURL);
	}

	public static String getRedirect(String viewPath, PageType pageType) {
		return format("redirect:%s/%s.htm", viewPath, pageType.getPageType()
				.toLowerCase());
	}

	public static String getRedirect(String viewPath, PageType pageType,
			Map<String, String> paramMap) {
		int count = 0;
		StringBuilder parms = new StringBuilder();
		for (String key : paramMap.keySet()) {
			try {
				count++;
				parms.append(key + "="
						+ UriUtils.encodeQueryParam(paramMap.get(key), "UTF-8"));

			} catch (UnsupportedEncodingException e) {
				parms.append(key + "=" + paramMap.get(key));
			} finally {
				if (count < paramMap.size())
					parms.append("&");
			}
		}

		return format("redirect:%s/%s.htm?%s", viewPath, pageType.getPageType()
				.toLowerCase(), parms.toString());

	}
	
	public static String getRedirectDownload(String viewPath, PageType pageType,
			Map<String, String> paramMap) {
		int count = 0;
		StringBuilder parms = new StringBuilder();
		for (String key : paramMap.keySet()) {
			try {
				count++;
				parms.append(key + "="
						+ UriUtils.encodeQueryParam(paramMap.get(key), "UTF-8"));

			} catch (UnsupportedEncodingException e) {
				parms.append(key + "=" + paramMap.get(key));
			} finally {
				if (count < paramMap.size())
					parms.append("&");
			}
		}

		return format("redirect:%s/%s.download?%s", viewPath, pageType.getPageType()
				.toLowerCase(), parms.toString());

	}

	public static String getExceptionErrorMessageKey(SystemException exception) {

		if (exception == null) {
			return null;
		}
		String messageKey = Constants.EXCEPTION_MESSAGES_PREFIX;
		String exceptionKey = ClassUtils.getShortClassName(exception, null)
				.toLowerCase();
		if (exceptionKey == null) {
			return null;
		}

		messageKey += exceptionKey;

		return messageKey;
	}

	public static String addExceptionError(Exception exception,
			BindingResult errors) {

		String message = null;

		if (exception instanceof SystemException) {

			SystemException sysExcep = (SystemException) exception;

			String messageKey = getExceptionErrorMessageKey(sysExcep);

			if (messageKey != null
					&& sysExcep.getErrorMessageArgList().size() != 0) {

				errors.reject(messageKey, sysExcep.getErrorMessageArgList()
						.toArray(new String[0]), null);
			} else {
				throw new SystemException();
			}
		}
		return message;
	}

	public static String getCurrentRequestedPage(HttpServletRequest request) {

		UrlPathHelper helper = new UrlPathHelper();

		String requestedURI = helper.getOriginatingRequestUri(request);
		String queryParam = helper.getOriginatingQueryString(request);
		
		if (queryParam != null) {
			requestedURI = requestedURI.concat("?" + queryParam);
		}

		return request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+requestedURI;
	}
}
